"""
课程管理模块 - 数据模型
"""
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from django.core.validators import MinValueValidator, MaxValueValidator
import uuid

from apps.core.models import TimeStampedModel

User = get_user_model()


class Course(TimeStampedModel):
    """
    课程模型
    核心教学单元，关联教师、学生和教学资源
    """
    class CourseType(models.TextChoices):
        REQUIRED = 'required', '必修课'
        ELECTIVE = 'elective', '选修课'
        PRACTICAL = 'practical', '实践课'
        ONLINE = 'online', '在线课程'
        LAB = 'lab', '实验课'

    class Status(models.TextChoices):
        DRAFT = 'draft', '草稿'
        ACTIVE = 'active', '进行中'
        PAUSED = 'paused', '暂停'
        COMPLETED = 'completed', '已完成'
        CANCELLED = 'cancelled', '已取消'

    # 基本信息
    code = models.CharField('课程代码', max_length=20, unique=True)
    name = models.CharField('课程名称', max_length=200)
    description = models.TextField('课程描述')
    type = models.CharField('课程类型', max_length=20, choices=CourseType.choices)
    status = models.CharField('状态', max_length=20, choices=Status.choices, default=Status.DRAFT)

    # 课程信息
    credits = models.DecimalField(
        '学分',
        max_digits=3,
        decimal_places=1,
        validators=[MinValueValidator(0.5), MaxValueValidator(20)]
    )
    total_hours = models.IntegerField('总学时', validators=[MinValueValidator(1)])
    theory_hours = models.IntegerField('理论学时', default=0)
    practice_hours = models.IntegerField('实践学时', default=0)

    # 关联教师
    instructors = models.ManyToManyField(
        User,
        related_name='teaching_courses',
        verbose_name='授课教师',
        limit_choices_to={'role': 'teacher'}
    )
    main_instructor = models.ForeignKey(
        User,
        on_delete=models.PROTECT,
        related_name='main_courses',
        verbose_name='主讲教师',
        limit_choices_to={'role': 'teacher'}
    )

    # 课程设置
    max_students = models.IntegerField('最大学生数', default=100)
    current_students = models.IntegerField('当前学生数', default=0)
    min_students = models.IntegerField('最少开课人数', default=10)

    # 时间安排
    start_date = models.DateField('开课日期')
    end_date = models.DateField('结课日期')
    registration_start = models.DateField('报名开始时间')
    registration_end = models.DateField('报名结束时间')

    # 课程资料
    syllabus = models.FileField('教学大纲', upload_to='courses/syllabus/', null=True, blank=True)
    materials = models.JSONField('课程资料', default=list, blank=True)

    # 评估方式
    assessment_methods = models.JSONField('评估方式', default=list, blank=True)
    passing_criteria = models.JSONField('及格标准', default=dict, blank=True)

    # 创建和管理
    creator = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='created_courses',
        verbose_name='创建者'
    )

    class Meta:
        db_table = 'courses'
        verbose_name = '课程'
        verbose_name_plural = '课程'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['code']),
            models.Index(fields=['status']),
            models.Index(fields=['type']),
            models.Index(fields=['start_date', 'end_date']),
            models.Index(fields=['main_instructor']),
        ]

    def __str__(self):
        return f"{self.code} - {self.name}"

    def is_full(self):
        """检查课程是否已满"""
        return self.current_students >= self.max_students

    def can_register(self):
        """检查是否可以报名"""
        today = timezone.now().date()
        return (
            self.status == self.Status.ACTIVE and
            self.registration_start <= today <= self.registration_end and
            not self.is_full()
        )

    def get_student_progress(self, student):
        """获取学生的学习进度"""
        enrollment = self.enrollments.filter(student=student).first()
        return enrollment.get_progress() if enrollment else None


class CourseEnrollment(TimeStampedModel):
    """
    课程注册
    学生选课记录
    """
    class Status(models.TextChoices):
        REGISTERED = 'registered', '已选课'
        DROPPED = 'dropped', '已退课'
        COMPLETED = 'completed', '已完成'
        FAILED = 'failed', '未通过'
        IN_PROGRESS = 'in_progress', '学习中'

    course = models.ForeignKey(
        Course,
        on_delete=models.CASCADE,
        related_name='enrollments',
        verbose_name='课程'
    )
    student = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='course_enrollments',
        verbose_name='学生',
        limit_choices_to={'role': 'student'}
    )

    # 状态和时间
    status = models.CharField('状态', max_length=20, choices=Status.choices, default=Status.REGISTERED)
    registration_date = models.DateTimeField('注册时间', auto_now_add=True)
    completion_date = models.DateTimeField('完成时间', null=True, blank=True)

    # 学习数据
    attendance_rate = models.DecimalField('出勤率', max_digits=5, decimal_places=2, default=0)
    assignment_scores = models.JSONField('作业成绩', default=list, blank=True)
    exam_scores = models.JSONField('考试成绩', default=list, blank=True)
    final_score = models.DecimalField('最终成绩', max_digits=5, decimal_places=2, null=True, blank=True)

    # 学习进度
    completed_modules = models.JSONField('已完成模块', default=list, blank=True)
    progress_percentage = models.IntegerField('学习进度', default=0)
    last_active_date = models.DateTimeField('最后活跃时间', null=True, blank=True)

    # 反馈和评价
    student_feedback = models.TextField('学生反馈', blank=True)
    instructor_comments = models.TextField('教师评语', blank=True)

    class Meta:
        db_table = 'course_enrollments'
        verbose_name = '课程注册'
        verbose_name_plural = '课程注册'
        unique_together = [['course', 'student']]
        indexes = [
            models.Index(fields=['course', 'status']),
            models.Index(fields=['student', 'status']),
            models.Index(fields=['registration_date']),
        ]

    def __str__(self):
        return f"{self.student.real_name} - {self.course.name}"

    def get_progress(self):
        """计算学习进度"""
        return {
            'progress_percentage': self.progress_percentage,
            'completed_modules': self.completed_modules,
            'last_active': self.last_active_date,
            'status': self.get_status_display()
        }

    def calculate_final_score(self):
        """计算最终成绩"""
        if not self.assignment_scores and not self.exam_scores:
            return None

        total_score = 0
        total_weight = 0

        # 作业成绩 (40%)
        if self.assignment_scores:
            assignment_avg = sum(self.assignment_scores) / len(self.assignment_scores)
            total_score += assignment_avg * 0.4
            total_weight += 0.4

        # 考试成绩 (60%)
        if self.exam_scores:
            exam_avg = sum(self.exam_scores) / len(self.exam_scores)
            total_score += exam_avg * 0.6
            total_weight += 0.6

        if total_weight > 0:
            return total_score / total_weight
        return None


class CourseModule(TimeStampedModel):
    """
    课程模块
    课程的章节或单元
    """
    course = models.ForeignKey(
        Course,
        on_delete=models.CASCADE,
        related_name='modules',
        verbose_name='课程'
    )

    # 模块信息
    title = models.CharField('模块标题', max_length=200)
    description = models.TextField('模块描述')
    order = models.IntegerField('顺序', validators=[MinValueValidator(1)])

    # 内容和资源
    content = models.TextField('模块内容')
    resources = models.JSONField('学习资源', default=list, blank=True)
    assignments = models.JSONField('作业任务', default=list, blank=True)

    # 时间安排
    start_date = models.DateField('开始日期', null=True, blank=True)
    end_date = models.DateField('结束日期', null=True, blank=True)
    estimated_hours = models.IntegerField('预计学习时长', default=2)

    # 完成条件
    required_materials = models.JSONField('必需材料', default=list, blank=True)
    completion_criteria = models.JSONField('完成标准', default=dict, blank=True)

    is_published = models.BooleanField('已发布', default=False)

    class Meta:
        db_table = 'course_modules'
        verbose_name = '课程模块'
        verbose_name_plural = '课程模块'
        unique_together = [['course', 'order']]
        ordering = ['course', 'order']
        indexes = [
            models.Index(fields=['course', 'order']),
            models.Index(fields=['is_published']),
        ]

    def __str__(self):
        return f"{self.course.name} - {self.title}"


class CourseSchedule(TimeStampedModel):
    """
    课程安排
    具体的上课时间和地点
    """
    course = models.ForeignKey(
        Course,
        on_delete=models.CASCADE,
        related_name='schedules',
        verbose_name='课程'
    )

    # 时间信息
    day_of_week = models.IntegerField(
        '星期几',
        choices=[
            (1, '周一'),
            (2, '周二'),
            (3, '周三'),
            (4, '周四'),
            (5, '周五'),
            (6, '周六'),
            (7, '周日'),
        ]
    )
    start_time = models.TimeField('开始时间')
    end_time = models.TimeField('结束时间')
    start_date = models.DateField('开始日期')
    end_date = models.DateField('结束日期')

    # 重复设置
    is_recurring = models.BooleanField('是否重复', default=True)
    frequency = models.CharField(
        '频率',
        max_length=20,
        choices=[
            ('weekly', '每周'),
            ('biweekly', '每两周'),
            ('monthly', '每月'),
        ],
        default='weekly'
    )

    # 地点和教师
    location = models.CharField('上课地点', max_length=200)
    instructor = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='teaching_schedules',
        verbose_name='授课教师',
        limit_choices_to={'role': 'teacher'}
    )

    # 备注
    notes = models.TextField('备注', blank=True)

    class Meta:
        db_table = 'course_schedules'
        verbose_name = '课程安排'
        verbose_name_plural = '课程安排'
        ordering = ['course', 'day_of_week', 'start_time']
        indexes = [
            models.Index(fields=['course', 'day_of_week']),
            models.Index(fields=['instructor', 'start_date']),
        ]

    def __str__(self):
        return f"{self.course.name} - {self.get_day_of_week_display()} {self.start_time}"


class CourseResource(TimeStampedModel):
    """
    课程资源
    课件、视频、文档等学习材料
    """
    class ResourceType(models.TextChoices):
        DOCUMENT = 'document', '文档'
        VIDEO = 'video', '视频'
        AUDIO = 'audio', '音频'
        IMAGE = 'image', '图片'
        LINK = 'link', '链接'
        ASSIGNMENT = 'assignment', '作业'
        QUIZ = 'quiz', '测验'

    course = models.ForeignKey(
        Course,
        on_delete=models.CASCADE,
        related_name='resources',
        verbose_name='课程'
    )

    # 资源信息
    title = models.CharField('资源标题', max_length=200)
    description = models.TextField('资源描述', blank=True)
    type = models.CharField('资源类型', max_length=20, choices=ResourceType.choices)

    # 文件或链接
    file = models.FileField('资源文件', upload_to='courses/resources/', null=True, blank=True)
    url = models.URLField('资源链接', null=True, blank=True)
    content = models.TextField('文本内容', blank=True)

    # 组织信息
    module = models.ForeignKey(
        CourseModule,
        on_delete=models.CASCADE,
        related_name='resources',
        verbose_name='所属模块',
        null=True,
        blank=True
    )
    order = models.IntegerField('顺序', default=0)

    # 使用信息
    is_mandatory = models.BooleanField('是否必需', default=False)
    download_count = models.IntegerField('下载次数', default=0)
    view_count = models.IntegerField('查看次数', default=0)

    # 创建者
    creator = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='created_resources',
        verbose_name='创建者'
    )

    class Meta:
        db_table = 'course_resources'
        verbose_name = '课程资源'
        verbose_name_plural = '课程资源'
        ordering = ['course', 'module', 'order']
        indexes = [
            models.Index(fields=['course', 'type']),
            models.Index(fields=['module', 'order']),
            models.Index(fields=['creator']),
        ]

    def __str__(self):
        return f"{self.course.name} - {self.title}"